package library.console;

import library.ErrorCode;
import library.ErrorMessage;
import library.controller.BookController;
import library.controller.LibrarianController;
import library.controller.ReaderController;
import library.entity.Book;
import library.entity.Librarian;
import library.entity.Reader;
import library.entity.User;

import java.sql.SQLException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class AdminMenu {
	Scanner scanner;
	BookController bookController;
    ReaderController readerController;
    LibrarianController librarianController;

	public AdminMenu(Scanner sc){
		scanner = sc;
		try {
			bookController = new BookController();
            readerController = new ReaderController();
            librarianController = new LibrarianController();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		showAdminMenu();
	}
	
	private void showAdminMenu(){
		int input;
		do{
            String [] options = {"User management","Book management","To main menu"};
			input = ConsoleUtilities.showMenu(scanner, "Administration Menu", options);
			
			switch(input) {
                case 1:
                    showUserManagementMenu();
                    break;
				case 2:
                    showBookManagementMenu();
					break;
			}
		} while (input != 3);
	}

    private void showUserManagementMenu(){
        int input;
        String [] options = {"Create Reader","Delete Reader","Create Librarian","Delete Librarian","Modify Reader","Modify Librarian","Return Admin menu"};
        do{
            input = ConsoleUtilities.showMenu(scanner, "User management", options);
            switch(input) {
                case 1:
                    newReader();
                    break;
                case 2:
                    deleteReader();
                    break;
                case 3:
                    newLibrarian();
                    break;
                case 4:
                    deleteLibrarian();
                    break;
                case 5:
                    modifyReader();
                    break;
                case 6:
                    modifiyLibrarian();
                    break;
                case 7:
                    return;
            }

            System.out.println("Press any key to continue...");
            scanner.nextLine();
        } while (input != options.length);
    }

    private void deleteLibrarian() {
        System.out.print("Enter librarian userName that want to delete: ");
        String input = scanner.nextLine();
        try {
            if(librarianController.delete(input))
                System.out.println("Librarian:" + input + "deleted.");
            else
                System.out.println("Librarian:" + input + "can not deleted. Error: " + librarianController.getError().getErrorMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void showBookManagementMenu(){
        int input;
        do{
            String [] options = {"Create Book","Delete Book","Return Admin menu"};
            input = ConsoleUtilities.showMenu(scanner, "User management", options);

            switch(input) {
                case 1:
                    createNewBook();
                    break;
                case 2:
                    deleteBook();
                    break;
                case 3:
                    return;
            }
        } while (input != 2);
    }

    private void deleteBook() {
        System.out.print("Enter book id want to delete: ");
        int id = scanner.nextInt();
        scanner.nextLine();
        Book bk = bookController.getBookById(id);
        if(bk == null)
            System.out.println("Book id " + id + "not found");

        if(bookController.deleteBook(bk)){
            System.out.println("Book " + id + "deleted");
        }
    }

    private void createNewBook() {
		System.out.println("Enter new book name: ");
		String bookName = scanner.nextLine();
		System.out.println("Enter new book ISBN: ");
        long isbn = 0;
        try {
            isbn = scanner.nextLong();
        } catch (InputMismatchException typeEx) {
            System.out.println("A number require for ISBN");
        }
        scanner.nextLine();
		Book newBook = new Book(bookName, isbn);
        if(bookController.createNewBook(newBook))
            System.out.println("Book " + bookName + " created.");
        else
            System.out.println("Book " + bookName + "can not created.");
	}

    private void deleteReader(){
        System.out.print("Enter reader that want to delete: ");
        String readerName = scanner.nextLine();
        if(readerController.delete(readerName)){
           System.out.println("Reader " + readerName + " deleted.");
        } else {
            ErrorMessage error = readerController.getError();
            if(error.getErrorCode() == ErrorCode.READER_NOT_FOUND)
                System.out.println("Reader " + readerName + " not found.");
            else if(error.getErrorCode() == ErrorCode.UNEXPECTED_ERROR){
                System.out.println("An unexpected error found: " + error.getException().getMessage());
            }
        }
    }

    private void newReader(){
        //TODO similar code to newLibrarian , need to refactoring
        System.out.print("Enter new reader user name: ");
        String readerLoginName = scanner.nextLine();
        System.out.print("Enter new reader full name: ");
        String readerFullName = scanner.nextLine();
        System.out.print("Enter new reader address: ");
        String address = scanner.nextLine();
        System.out.print("Enter new telephone: ");
        String tel = scanner.nextLine();
        Reader newReader = new Reader(readerLoginName,readerFullName,address,tel);

        if(readerController.create(newReader)){
            String message = String.format(
                    "User name: %s \n" +
                            "Full name: %s \n" +
                            "Address  : %s \n" +
                            "Telephone: %s \n",
                    readerLoginName, readerFullName, address, tel);
            ConsoleUtilities.printBox("New reader created successful", message, 35);
        } else {
            getCreateErrorMessage(newReader);
        }
    }

    private void newLibrarian(){
        System.out.print("Enter new librarian userName: ");
        String userName = scanner.nextLine();
        System.out.print("Enter new librarian full name: ");
        String fullName = scanner.nextLine();
        System.out.print("Enter new password: ");
        String password = scanner.nextLine();
        Librarian newLibrarian = new Librarian(userName, password);
        newLibrarian.setFullName(fullName);
        System.out.print("Is administrator? (Enter Y/N): ");
        if(scanner.nextLine().equalsIgnoreCase("Y"))
            newLibrarian.setAdminRight(true);

        if(librarianController.create(newLibrarian)){
            System.out.printf("Librarian %s, created.\n", newLibrarian.getUserName());
        } else{
            getCreateErrorMessage(newLibrarian);
        }
    }

    private void getCreateErrorMessage(User user) {
        ErrorMessage error;
        if(user.getClass() == Librarian.class){
            error = librarianController.getError();
        } else if(user.getClass() == Reader.class){
            error = readerController.getError();
        } else {
            System.out.println("Class: " + user.getClass().getName() + " not match, can not get error message!");
            return;
        }

        if(error.getErrorCode() == ErrorCode.DUPLICATE_USER_FOUND)
            System.out.println("User can not create, " + user.getUserName() + " already exist.");
        else if(error.getErrorCode() == ErrorCode.UNEXPECTED_ERROR)
            System.out.println("An unexpected error found: " + error.getException().getMessage());
    }

    private void modifiyLibrarian(){
        System.out.print("Enter Librarian name that want to modify: ");
        String username = scanner.nextLine();
        Librarian librarian = librarianController.getLibrarian(username);
        if(librarian == null){
            System.out.println(username + " not exist!");
            return;
        }

        int option;
        do{
            String[] field = {
                    "Username : " + librarian.getUserName(),
                    "Full name: " + librarian.getFullName(),
                    "Change password",
                    "Is Admin : " + (librarian.isAdmin() ? "True " : "False"),
                    "Commit change",
                    "Discard change"
            };

            option = ConsoleUtilities.showMenu(scanner,"Please select field to modify",field);
            String value = "";
            if(option < 4){
                System.out.print("Enter value: ");
                value = scanner.nextLine();
            }
            switch (option){
                case 1:
                    librarian.setUserName(value);
                    break;
                case 2:
                    librarian.setFullName(value);
                    break;
                case 3:
                    librarian.setPassword(value);
                    break;
                case 4:
                    librarian.setAdminRight(!librarian.isAdmin());
                    break;
                case 5:
                    if(librarianController.update(librarian)) {                    	
                        System.out.println("Librarian update successful");
                    } else {
                        System.out.println("Librarian can not update." + librarianController.getError().getErrorMessage());
                    }
                    return;
            }
        } while(option < 5);
    }


    private void modifyReader(){
        System.out.print("Enter Reader name that want to modify: ");
        String username = scanner.nextLine();
        Reader reader = readerController.getReader(username);
        if(reader==null){
            System.out.println(username + " not exist!");
            return;
        }

        int option;
        do{
            String[] field = {
                    "Username : " + reader.getUserName(),
                    "Full name: " + reader.getFullName(),
                    "Address  : " + reader.getAddress(),
                    "Tel      : " + reader.getTel(),
                    "Commit change",
                    "Discard change"
            };

            option = ConsoleUtilities.showMenu(scanner,"Please select field to modify",field);
            String value = "";
            if(option < 5){
                System.out.print("Enter value: ");
                value = scanner.nextLine();
            }
            switch (option){
                case 1:
                    reader.setUserName(value);
                    break;
                case 2:
                    reader.setFullName(value);
                    break;
                case 3:
                    reader.setAddress(value);
                    break;
                case 4:
                    reader.setTel(value);
                    break;
                case 5:
                    if(readerController.update(reader)) {
                        System.out.println("Reader update successful");
                    } else {
                        System.out.println("Reader can not update. " + readerController.getError().getErrorMessage());
                    }
                    return;
            }
        } while(option < 5);
    }
}
